<template>
  <div class="flex">
    <el-card class="w-1/5 tpl" :gutter="12" shadow="always">
      <template #header>
        <div class="card-header">
          <span>模板列表</span>
        </div>
      </template>
      <el-input v-model="filterText" placeholder="搜索文件夹" />
      <el-scrollbar height="650">
        <el-tree
          ref="treeRef"
          node-key="id"
          default-expand-all:false
          :data="folderOptions"
          :props="treeProps"
          :highlight-current="true"
          :filter-node-method="filterNode"
          :expand-on-click-node="false"
          @node-click="handleFolderClick"
        />
      </el-scrollbar>
    </el-card>
    <el-card class="w-4/5 tpl" style="margin-left: 10px" :gutter="12" shadow="hover">
      <!-- 搜索 -->
      <ContentWrap>
        <el-form
          class="-mb-15px"
          :model="queryParams"
          ref="queryFormRef"
          :inline="true"
          label-width="68px"
        >
          <el-form-item label="名称" prop="filename">
            <el-input
              v-model="queryParams.filename"
              placeholder="请输入名称"
              clearable
              @keyup.enter="handleQuery"
              class="!w-240px"
            />
          </el-form-item>
          <el-form-item>
            <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
            <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
            <!-- 操作：新增 -->
            <XButton
              type="primary"
              preIcon="ep:zoom-in"
              :title="t('action.add')"
              v-hasPermi="['cms:tpl:save']"
              @click="openForm('create', queryParams.root)"
            />
            <XButton
              type="primary"
              preIcon="ep:zoom-in"
              :title="t('cms.createDir')"
              v-hasPermi="['cms:tpl:save']"
              @click="handleCreateDir()"
            />
            <XButton
              type="primary"
              preIcon="ep:upload"
              :title="t('cms.upload')"
              v-hasPermi="['cms:tpl:save']"
              @click="uploadDialogVisible = true"
            />
            <!-- 操作：导入 -->
            <XButton
              type="warning"
              preIcon="ep:upload"
              :title="t('action.import')"
              v-hasPermi="['cms:tpl:tplImport']"
              @click="importDialogVisible = true"
            />
            <!-- 操作：导出 -->
            <XButton
              type="warning"
              preIcon="ep:download"
              :title="t('action.export')"
              v-hasPermi="['cms:tpl:export']"
              @click="handleExport()"
            />
          </el-form-item>
        </el-form>
      </ContentWrap>
      <!-- 列表 -->
      <ContentWrap>
        <el-table v-loading="loading" :data="list">
          <el-table-column label="名称" key="filename">
            <template #default="{ row }">
              <el-tag v-if="!row.editable" @click="handleFolderClick(row)">{{
                row.filename
              }}</el-tag>
              <el-tag v-else @click="openForm('update', queryParams.root, row.name)">
                {{ row.filename }}</el-tag
              >
            </template>
          </el-table-column>
          <el-table-column label="大小" align="center" prop="size" />
          <el-table-column
            label="最后修改时间"
            align="center"
            prop="lastModifiedDate"
            :formatter="dateFormatter"
            width="180"
          />
          <el-table-column label="操作" align="center" width="220">
            <template #default="{ row }">
              <div class="flex justify-center items-center">
                <!-- 操作：编辑 -->
                <XTextButton
                  preIcon="ep:edit"
                  :title="t('action.edit')"
                  v-hasPermi="['cms:tpl:update']"
                  v-if="row.editable"
                  @click="openForm('update', queryParams.root, row.name)"
                />
                <!-- 操作：删除 -->
                <XTextButton
                  preIcon="ep:delete"
                  :title="t('action.del')"
                  v-hasPermi="['cms:tpl:delete']"
                  @click="handleDelete(row.name)"
                />
                <XTextButton
                  preIcon="ep:document"
                  :title="t('action.version')"
                  v-hasPermi="['cms:tpl:update']"
                  v-if="row.editable"
                  @click="handleVersion(row.name)"
                />
              </div>
            </template>
          </el-table-column>
        </el-table>
      </ContentWrap>
    </el-card>
  </div>
  <TplForm ref="formRef" @success="getList" />
  <!--版本分页-->
  <Dialog v-model="versionDialogVisible" :title="t('action.version')" width="80%">
    <ContentWrap>
      <el-table
        v-loading="versionLoading"
        :table-layout="tableLayout"
        :data="versionDatas"
        ref="versionTableRef"
        row-key="id"
      >
        <el-table-column label="模板" align="center" prop="tplPath" />
        <el-table-column
          label="创建时间"
          align="center"
          prop="createTime"
          :formatter="dateFormatter"
        />
        <el-table-column label="操作" align="center">
          <template #default="{ row }">
            <!-- 操作：查看版本 -->
            <XTextButton
              v-hasPermi="['cms:tpl-version:query']"
              preIcon="ep:view"
              :title="t('action.detail')"
              @click="handleVersionDetail(row.id)"
            />
            <!-- 操作：恢复当前版本 -->
            <XTextButton
              v-hasPermi="['cms:tpl:update']"
              preIcon="ep:refresh"
              :title="t('action.restore')"
              @click="handleRestore(row.id)"
            />
            <!-- 操作：删除版本数据 -->
            <XTextButton
              v-hasPermi="['cms:tpl-version:query']"
              preIcon="ep:delete"
              :title="t('action.del')"
              @click="handleDelVersion(row.id)"
            />
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <Pagination
        :total="versionTotal"
        v-model:page="versionQueryParams.pageNo"
        v-model:limit="versionQueryParams.pageSize"
        @pagination="getFileVersionList"
      />
    </ContentWrap>
  </Dialog>
  <!--版本详情-->
  <Dialog v-model="modelVisible" :title="t('action.detail')" width="60%">
    <ContentWrap>
      <el-row>
        <el-col :span="24">
          <el-form-item label="内容">
            <el-input
              v-model="detailData.tplSource"
              :rows="30"
              type="textarea"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <!-- 按钮：恢复此版本 -->
      <XButton
          v-hasPermi="['cms:tpl:update']"
          preIcon="ep:refresh"
          :title="t('action.restore')"
          @click="handleRestore(detailData.id)"
      />
      <!-- 按钮：关闭 -->
      <XButton  :title="t('dialog.close')" @click="modelVisible = false" />
    </ContentWrap>
  </Dialog>
  <!-- 导入 -->
  <Dialog v-model="importDialogVisible" :title="importDialogTitle">
    <el-form class="drawer-multiColumn-form" label-width="150px">
      <el-form-item label="文件上传 :">
        <el-upload
          ref="uploadImportRef"
          :action="importUrl"
          :headers="uploadHeaders"
          :drag="true"
          :limit="1"
          :multiple="false"
          :show-file-list="true"
          :disabled="uploadImportDisabled"
          :on-exceed="handleExceed"
          :on-success="handleFileSuccess"
          :on-error="handleUploadError"
          :auto-upload="false"
          accept=".zip"
        >
          <Icon icon="ep:upload-filled" />
          <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
          <template #tip>
            <div class="el-upload__tip">请上传 .zip 标准格式文件</div>
          </template>
        </el-upload>
      </el-form-item>
    </el-form>
    <template #footer>
      <!-- 按钮：保存 -->
      <XButton
        type="warning"
        preIcon="ep:upload-filled"
        :title="t('action.import')"
        @click="submitImportFileForm()"
      />
      <!-- 按钮：关闭 -->
      <XButton :title="t('dialog.close')" @click="importDialogVisible = false" />
    </template>
  </Dialog>
  <!-- 导出 -->
  <Dialog v-model="exportDialogVisible" :title="exportDialogTitle" width="500px">
    <el-form class="drawer-multiColumn-form" label-width="150px">
      <el-form-item label="模板文件夹:">
        <el-select v-model="solution" placeholder="Select" size="large">
          <el-option v-for="item in solutions" :key="item" :label="item" :value="item" />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <!-- 按钮：导出 -->
      <XButton
        type="warning"
        preIcon="ep:upload-filled"
        :title="t('action.export')"
        @click="handleTplDownload()"
      />
      <!-- 按钮：关闭 -->
      <XButton :title="t('dialog.close')" @click="exportDialogVisible = false" />
    </template>
  </Dialog>
  <!--创建文件夹--->
  <Dialog v-model="createDirDialogVisible" :title="createDirDialogTitle" width="500px">
    <el-form class="drawer-multiColumn-form" label-width="150px">
      <el-form-item label="模板文件夹:">
        <el-input v-model="dirName" />
      </el-form-item>
    </el-form>
    <template #footer>
      <XButton
        type="warning"
        preIcon="ep:upload-filled"
        :title="t('action.save')"
        @click="handleSaveDir()"
      />
      <!-- 按钮：关闭 -->
      <XButton :title="t('dialog.close')" @click="createDirDialogVisible = false" />
    </template>
  </Dialog>
  <!---上传文件-->
  <Dialog v-model="uploadDialogVisible" :title="uploadDialogTitle">
    <el-upload
      ref="uploadRef"
      :action="uploadTplUrl"
      :headers="uploadHeaders"
      :data="uploadData"
      :drag="true"
      :multiple="true"
      :show-file-list="true"
      :disabled="uploadDisabled"
      :before-upload="beforeUpload"
      :on-success="handleFileSuccess"
      :on-error="handleUploadError"
      :auto-upload="false"
      accept=".html"
    >
      <Icon icon="ep:upload-filled" />
      <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
      <template #tip>
        <div class="el-upload__tip">请上传 .html 标准格式文件</div>
      </template>
    </el-upload>
    <template #footer>
      <!-- 按钮：保存 -->
      <XButton
        type="primary"
        preIcon="ep:upload-filled"
        :title="t('action.save')"
        @click="submitFileForm()"
      />
      <!-- 按钮：关闭 -->
      <XButton :title="t('dialog.close')" @click="uploadDialogVisible = false" />
    </template>
  </Dialog>
</template>
<script setup lang="ts" name="TPL">
import TplForm from './TplForm.vue'
import type { ElTree, UploadInstance, UploadRawFile } from 'element-plus'
import { handleTree } from '@/utils/tree'
import download from '@/utils/download'
import { dateFormatter } from '@/utils/formatTime'
import { getAccessToken, getTenantId } from '@/utils/auth'
import { treeProps } from './tpl.data'
import { TplListVo } from '@/api/cms/tpl/types'
import { formatTime } from '@/utils/index'
import * as TplApi from '@/api/cms/tpl'
import { getSiteHeader } from '@/utils/cmscommon'

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数
const queryParams = reactive({
  root: '',
  filename: null
})

const queryFormRef = ref() // 搜索的表单

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await TplApi.getTplListApi(queryParams)
    list.value = data
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, root: string, name?: string) => {
  formRef.value.open(type, root, name)
}

// ========== 创建左侧树结构 ==========
const filterText = ref('')
const folderOptions = ref<Tree[]>([]) // 树形结构
const treeRef = ref<InstanceType<typeof ElTree>>()
const getTree = async () => {
  const res = await TplApi.getTplTreeApi()
  folderOptions.value.push(...handleTree(res))
}
const getSolutions = async () => {
  const res = await TplApi.getTplListApi()
  res.forEach((e: TplListVo) => {
    solutions.value.push(e.filename)
  })
}

const filterNode = (value: string, data: Tree) => {
  if (!value) return true
  return data.name.includes(value)
}
const handleFolderClick = async (row: { [key: string]: any }) => {
  queryParams.root = row.name
  await getList()
}
watch(filterText, (val) => {
  treeRef.value!.filter(val)
})
// ========== CRUD 相关 ==========
const handleExport = async () => {
  exportDialogVisible.value = true
}

const handleCreateDir = async () => {
  createDirDialogVisible.value = true
}

/** 删除按钮操作 */
const handleDelete = async (name: string) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await TplApi.deleteTplApi(name)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
  } catch {}
}

// ========== 导入相关 ==========
const importDialogVisible = ref(false)
const importDialogTitle = ref('模板导入')
const handleTplDownload = async () => {
  const res = await TplApi.exportApi(solution.value)
  const day = formatTime(new Date(), 'yyyy-MM-dd')
  download.zip(res, `模版${day}.zip`)
}
// 文件上传
const uploadDialogVisible = ref(false)
const uploadDialogTitle = ref('上传')
const uploadDisabled = ref(false)
const uploadImportDisabled = ref(false)
const uploadRef = ref<UploadInstance>()
const uploadImportRef = ref<UploadInstance>()
const uploadHeaders = ref()
const uploadData = ref()
let uploadTplUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/cms/tpl/upload'
let importUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/cms/tpl/import'
// 文件上传之前判断
const beforeUpload = (file: UploadRawFile) => {
  const isHtml = file.type === 'text/html'
  if (!isHtml) message.error('上传文件只能是 html 格式!')
  return isHtml
}
// 文件上传
const submitFileForm = () => {
  uploadHeaders.value = {
    Authorization: 'Bearer ' + getAccessToken(),
    'tenant-id': getTenantId(),
    zrcms_site_id: getSiteHeader()
  }
  //上传目标文件夹
  uploadData.value = {
    root: queryParams.root || ''
  }
  uploadDisabled.value = true
  uploadRef.value!.submit()
}
//模板导入上传
const submitImportFileForm = () => {
  uploadHeaders.value = {
    Authorization: 'Bearer ' + getAccessToken(),
    'tenant-id': getTenantId(),
    zrcms_site_id: getSiteHeader()
  }
  uploadImportDisabled.value = true
  uploadImportRef.value!.submit()
}

// 文件上传成功
const handleFileSuccess = async (response: any): Promise<void> => {
  if (response.code !== 0) {
    uploadDisabled.value = false
    message.error(response.msg)
    return
  }
  message.success('上传成功')
  uploadDialogVisible.value = false
  uploadDisabled.value = false

  uploadImportDisabled.value = false
  importDialogVisible.value = false
  await getList()
}
// 文件数超出提示
const handleExceed = (): void => {
  message.error('最多只能上传一个文件！')
}
// 上传错误提示
const handleUploadError = (): void => {
  message.error('导入数据失败，请您重新上传！')
  uploadDisabled.value = false
  uploadImportDisabled.value = false
  uploadImportRef.value?.clearFiles
  uploadRef.value?.clearFiles
}

//导出代码
const exportDialogVisible = ref(false)
const exportDialogTitle = ref('模板导出')
const solution = ref('default')
const solutions = ref([])

const createDirDialogVisible = ref(false)
const createDirDialogTitle = ref('创建文件夹')
const dirName = ref('')
const handleSaveDir = async () => {
  const data = {
    dirName: dirName.value,
    root: queryParams.root
  }
  try {
    await TplApi.createDirApi(data)
  } finally {
    // unref(formRef)?.setSchema(allSchemas.formSchema)
    // 刷新列表
    await getList()
    loading.value = false
  }
  message.success(t('common.createSuccess'))
  dirName.value = ''
  createDirDialogVisible.value = false
}
//版本管理
const tableLayout = ref('auto')
const versionLoading = ref(true) // 列表的加载中
const versionTotal = ref(0) // 列表的总页数
const versionDatas = ref([]) // 列表的数据
const versionTableRef = ref() // 表格的 Ref

/** 查询版本列表 */
const getFileVersionList = async () => {
  versionLoading.value = true
  try {
    const data = await TplApi.getTplVersionListApi(versionQueryParams)
    versionDatas.value = data.list
    versionTotal.value = data.total
  } finally {
    versionLoading.value = false
  }
}
const versionDialogVisible = ref<boolean>(false)
const versionQueryParams = reactive({
  tplPath: '',
  pageNo: 1,
  pageSize: 20
})
const handleVersion = async (filename: string) => {
  versionQueryParams.tplPath = filename
  versionDialogVisible.value = true
  await getFileVersionList()
}
const handleDelVersion = async (id:number) => {
  await TplApi.deleteTplVersionApi(id)
  getFileVersionList()
}
const modelVisible = ref(false) // 是否显示弹出层
const handleRestore = async (id:number) => {
  await TplApi.restoreTplApi(id)
  getFileVersionList()
  modelVisible.value = false
  versionDialogVisible.value = false
}
// 版本详情操作
const detailData = ref() // 详情 Ref
const handleVersionDetail = async (rowId: number) => {
  const res = await TplApi.getTplVersionApi(rowId)
  detailData.value = res
  modelVisible.value = true
}
// ========== 初始化 ==========
onMounted(async () => {
  await getTree()
  await getList()
  await getSolutions()
})
</script>

<style scoped>
.tpl {
  height: 780px;
  max-height: 800px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.el-link {
  margin-right: 8px;
}

.el-link .el-icon--right.el-icon {
  vertical-align: text-bottom;
}
</style>
